package dk.mirasola.systemtraining.bridgewidgets.shared.factory;

import dk.mirasola.systemtraining.bridgewidgets.shared.model.Bid;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.BiddingSequence;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.Seat;

public class BiddingSequenceFactory {
    private static final Seat[] FORWARD_SEATS = new Seat[]{Seat.NORTH, Seat.EAST, Seat.SOUTH, Seat.WEST};
    private static final String PROPERTY_DELIMETER = "#";
    private static final String BID_DELIMITER = "-";
    private static final String ROUND_DELIMITER = ";";
    private static final String NULLBID = "%";

    private BiddingSequenceFactory() {
    }

    public static String biddingSequenceToString(BiddingSequence biddingSequence) {
        StringBuffer str = new StringBuffer();
        str.append(SeatFactory.seatToString(biddingSequence.getDealer()));
        str.append(PROPERTY_DELIMETER);
        if (biddingSequence.isFinish()) {
            str.append("t");
        } else {
            str.append("f");
        }
        str.append(PROPERTY_DELIMETER);
        for (int i = 1; i <= biddingSequence.getRoundsCount(); i++) {
            for (Seat seat : FORWARD_SEATS) {
                Bid bid = biddingSequence.getBid(i, seat);
                if (bid != null) {
                    str.append(BidFactory.bidToString(bid));
                } else {
                    str.append(NULLBID);
                }
                if (seat != Seat.WEST) {
                    str.append(BID_DELIMITER);
                }
            }
            if (i < biddingSequence.getRoundsCount()) {
                str.append(ROUND_DELIMITER);
            }
        }

        return str.toString();
    }

    public static BiddingSequence stringToBiddingSequence(String encodeStr) {
        String[] props = encodeStr.split(PROPERTY_DELIMETER);
        if (props.length != 2 && props.length != 3) {
            throw new RuntimeException("Cannot parse '" + encodeStr + "' to a bidding sequence");
        }
        Seat dealer = SeatFactory.stringToSeat(props[0]);
        boolean finish = "t".equals(props[1]);


        BiddingSequence.Builder builder = new BiddingSequence.Builder(dealer, finish);
        if (props.length == 3) {
            String[] rounds = props[2].split(ROUND_DELIMITER);
            for (int i = 0; i < rounds.length; i++) {
                String roundStr = rounds[i];
                String[] bids = roundStr.split(BID_DELIMITER);
                if (bids.length != 4) {
                    throw new RuntimeException("Cannot parse '" + encodeStr + "' to a bidding sequence");
                }
                for (int j = 0; j < bids.length; j++) {
                    String bidStr = bids[j];
                    if (!NULLBID.equals(bidStr)) {
                        Bid bid = BidFactory.stringToBid(bidStr);
                        builder.addBid(i + 1, FORWARD_SEATS[j], bid);
                    }
                }
            }
        }
        return builder.create();
    }
}
